#ifndef __IINVENTORY_HPP__
#define __IINVENTORY_HPP__

#include <cstdint>
#include "Engine/Vector3.hpp"

using namespace PocketSurvival::Engine;

/**
 * 方块值都使用 int32_t 来表示
 * 背包里的物品位置以及数量都不应该存在负数的情况，
 * 所以这里使用 uint32_t 来表示，但是到客户端则
 * 可能需要以 int32_t 来传输
*/

namespace PocketSurvival
{
	struct ComponentBlockEntity;

	struct Slot
    {
        int32_t value = 0;			// 方块值
        uint32_t count = 0;			// 数量
    };
	struct IInventory
	{
		uint32_t id = 0;
		uint32_t visibleSlotsCount = 0;
		uint32_t activeSlotIndex = 0;

		ComponentBlockEntity* blockEntity = nullptr;

		inline virtual void setActiveSlotIndex(uint32_t index);
		inline virtual uint32_t getActiveSlotIndex();
		inline virtual void setVisibleSlotsCount(uint32_t count);
		inline virtual uint32_t getVisibleSlotsCount();

		virtual uint32_t slotsCount() = 0;
		virtual void setSlotValue(uint32_t slotIndex, int32_t cellValue, uint32_t cellCount) = 0;
		virtual int32_t getSlotValue(uint32_t slotIndex) = 0;
		virtual uint32_t getSlotCount(uint32_t slotIndex) = 0;
		virtual void onSlotChange(uint32_t slotIndex) = 0;
		virtual uint32_t getSlotCapacity(uint32_t slotIndex, int32_t cellValue) = 0;
		virtual uint32_t getSlotProcessCapacity(uint32_t slotIndex, int32_t cellValue) = 0;
		virtual void addSlotItems(uint32_t slotIndex, int32_t cellValue, uint32_t count) = 0;
		virtual bool addNetSlotItems(uint32_t slotIndex, int32_t cellValue, uint32_t count) = 0;
		virtual void processSlotItems(IInventory *sourceInventory, uint32_t sourceSlotIndex, uint32_t slotIndex, int32_t cellValue, uint32_t count, uint32_t processCount, int32_t &outProcessedValue, uint32_t &outProcessedCount) = 0;
		virtual uint32_t removeSlotItems(uint32_t slotIndex, uint32_t count) = 0;
		virtual uint32_t removeNetSlotItems(uint32_t slotIndex, uint32_t count) = 0;
		virtual void dropAllItems(const Vector3 &position) = 0;
		virtual void dropSlotItems(uint32_t slotIndex, const Vector3 &position, const Vector3 &velocity) = 0;
	};

	inline void IInventory::setActiveSlotIndex(uint32_t index)
	{
		activeSlotIndex = index;
	}
	inline uint32_t IInventory::getActiveSlotIndex()
	{
		return activeSlotIndex;
	}
	inline void IInventory::setVisibleSlotsCount(uint32_t count)
	{
		visibleSlotsCount = count;
	}
	inline uint32_t IInventory::getVisibleSlotsCount()
	{
		return visibleSlotsCount;
	}

}

#endif